﻿
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace EHU_InterfaceProgramming
{
    /// <summary>
    ///Handles the codeOutput panel
    ///Included are methods for printing instructions or code out to this panel appropriately
    ///Author: James Wilkinson & Joe Bolton
    /// </summary>
    public class outputCodeDisplay
    {
        // Keep track of the richtextbox object
        public RichTextBox codeOutputWindow;
        // Keep track of the number indentions currently active
        private int indent;

        public MainWindow mainwind;

        /// <summary>
        /// Assign the object representing the code output window so we can keep track of it
        /// </summary>
        /// <param name="window"></param>
        public outputCodeDisplay(RichTextBox window, MainWindow mw)
        {
            this.codeOutputWindow = window;
            this.mainwind = mw;
        }

        /// <summary>
        /// Prints a message to the code output console.
        /// Does not use indention.
        /// </summary>
        /// <param name="msg">Message to print.</param>

        public void print(String msg)
        {
            TextRange rangeOfText1 = new TextRange(codeOutputWindow.Document.ContentEnd, codeOutputWindow.Document.ContentEnd);
            rangeOfText1.Text = msg;
            rangeOfText1.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Black);
        }



        /// <summary>
        /// Prints a message to the code output console on a new line.
        /// Does not use indention
        /// </summary>
        /// <param name="msg">Message to Print.</param>
        public void printcodeln(String msg)
        {
            this.print("\n" + msg);
        }


        /// <summary>
        /// The difference between printing code here and
        ///using the other print method is indention.
        ///This method indents the code accordingly based on the
        ///opening and closing braces.
        /// </summary>
        /// <param name="code">The code to print</param>
        public void printCode(String code)
        {
            String indentions = "";
            for (int i = 0; i < this.indent; i++)
            {
                if (i == 0)
                {
                    indentions = "    ";
                    continue;
                }
                indentions = indentions + "    ";

            }
            print(indentions + code);
        }


        /// <summary>
        /// This method prints code on a new line. Uses indention - useful for braces.
        /// </summary>
        /// <param name="code"> The code to output.</param>
        public void printCodeLn(String code)
        {
            this.print("\n");
            String indentions = "";
            for (int i = 0; i < this.indent; i++)
            {
                if (i == 0)
                {
                    indentions = "    ";
                    continue;
                }
                indentions = indentions + "    ";

            }
            this.print(indentions + code);
        }


        /// <summary>
        /// Prints to the code output window in the specified color used for syntax highlighting. Uses indention
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="hexcolor"></param>
        public void printColorCode(String msg, String hexcolor)
        {
            // Convert the hexcolor param into hex code her
            var converter = new System.Windows.Media.BrushConverter();
            var brush = (Brush)converter.ConvertFromString(hexcolor);

            // Prefix spaces for indention
            String indentions = "";
            for (int i = 0; i < this.indent; i++)
            {
                if (i == 0)
                {
                    indentions = "    ";
                    continue;
                }
                indentions = indentions + "    ";
            }
            // Now print it to the output window in the color
            TextRange rangeOfText1 = new TextRange(codeOutputWindow.Document.ContentEnd, codeOutputWindow.Document.ContentEnd);
            rangeOfText1.Text = indentions + msg;
            rangeOfText1.ApplyPropertyValue(TextElement.ForegroundProperty, brush);
        }



        /// <summary>
        /// Adds an if statement to the code output
        /// </summary>
        public void ifStatement()
        {
            this.printColorCode("if", "#0066CC");
        }

        /// <summary>
        /// Adds a return statement to the output window
        /// </summary>
        public void returnStatement()
        {
            this.printColorCode("return;", "#0066CC");
        }

        /// <summary>
        /// Adds a "class" in syntax highlighting to the output window.
        /// </summary>
        /// <param name="Visibility">Visibility of the class represented in string format. Valid inputs are Public, Private, or Protected. </param>
        /// <param name="ReturnType">Return Type of the class, represented as a string. Valid inputs are any data type. Defaults to void.</param>
        /// <param name="StaticClass"> Boolean value, true if class is static, false if it is not.</param>
        /// <param name="ClassName"> The name of the class to construct, as a string</param>
        public void ClassStatement(String Visibility, Boolean StaticClass, String ClassName = "Class1", String ReturnType = "void")
        {
            String code = "";
            if (StaticClass == true)
            {
                code = Visibility + " static " + ReturnType + " " + ClassName;
            }
            this.printColorCode(code, "#0066CC");
        }


        /// <summary>
        /// Adds an opening brace.
        /// </summary>
        public void openingBrace()
        {
            this.printCodeLn("{\n");
            this.indent++;
        }
        /// <summary>
        /// Adds a closing brace.
        /// </summary>
        public void closingBrace()
        {
            this.indent--;
            this.printCodeLn("}\n");
        }

        public void forLoop(int iterations, int startval =0, char IncreaseorDecrease = '+')
        {
                      
            string code = "for (int i = 0; i <= 5; i++)";
            this.printColorCode(code, "00C925");

        }

        /// <summary>
        /// Add a comment to the code accordingly. Displays comments in green then reverts back to the original foreground color
        /// </summary>
        /// <param name="comment">Comment to add. Omit the  leading "//"</param>
        public void addComment(String comment)
        {
            this.printColorCode("// " + comment + "\n", "#009900");
        }

        /// <summary>
        /// Save the code output to the specified file name. The location
        /// will always bee on the desktop
        /// </summary>
        /// <param name="filename"></param>
        public void saveCodeToFile(String filename = "program1.txt")
        {
            StreamWriter wr = File.CreateText(
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), filename));

            try 
            {
                wr.Write(new TextRange(codeOutputWindow.Document.ContentStart, codeOutputWindow.Document.ContentEnd).Text);
                wr.Flush();
            }
            finally 
            {
                if (wr != null)
                    wr.Close();
                mainwind.showActionText("File saved on the desktop as " + filename);
            }
        }
    }
}